"""
统一日志管理器 - 解决日志记录不统一问题
"""

import logging
import logging.handlers
import os
import sys
import time
import functools
from datetime import datetime
from pathlib import Path
from typing import Optional, Callable, Any


class LoggerManager:
    """统一日志管理器"""
    
    def __init__(self, 
                 name: str = "downloader",
                 log_dir: str = "logs",
                 log_level: str = "INFO",
                 max_file_size: int = 10 * 1024 * 1024,  # 10MB
                 backup_count: int = 5):
        """初始化日志管理器
        
        Args:
            name: 日志器名称
            log_dir: 日志目录
            log_level: 日志级别
            max_file_size: 单个日志文件最大大小
            backup_count: 保留的日志文件数量
        """
        self.name = name
        self.log_dir = Path(log_dir)
        self.log_level = getattr(logging, log_level.upper(), logging.INFO)
        self.max_file_size = max_file_size
        self.backup_count = backup_count
        
        # 创建日志目录
        self.log_dir.mkdir(exist_ok=True)
        
        # 初始化日志器
        self.logger = self._setup_logger()
    
    def _setup_logger(self) -> logging.Logger:
        """设置日志器"""
        logger = logging.getLogger(self.name)
        logger.setLevel(self.log_level)
        
        # 避免重复添加处理器
        if logger.handlers:
            return logger
        
        # 创建格式器
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        
        # 控制台处理器
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setLevel(self.log_level)
        console_handler.setFormatter(formatter)
        logger.addHandler(console_handler)
        
        # 文件处理器
        log_file = self.log_dir / f"{self.name}.log"
        file_handler = logging.handlers.RotatingFileHandler(
            log_file,
            maxBytes=self.max_file_size,
            backupCount=self.backup_count,
            encoding='utf-8'
        )
        file_handler.setLevel(self.log_level)
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)
        
        # 错误日志单独文件
        error_log_file = self.log_dir / f"{self.name}_error.log"
        error_handler = logging.handlers.RotatingFileHandler(
            error_log_file,
            maxBytes=self.max_file_size,
            backupCount=self.backup_count,
            encoding='utf-8'
        )
        error_handler.setLevel(logging.ERROR)
        error_handler.setFormatter(formatter)
        logger.addHandler(error_handler)
        
        return logger
    
    def debug(self, message: str, *args, **kwargs):
        """记录调试信息"""
        self.logger.debug(message, *args, **kwargs)
    
    def info(self, message: str, *args, **kwargs):
        """记录信息"""
        self.logger.info(message, *args, **kwargs)
    
    def warning(self, message: str, *args, **kwargs):
        """记录警告"""
        self.logger.warning(message, *args, **kwargs)
    
    def error(self, message: str, *args, **kwargs):
        """记录错误"""
        self.logger.error(message, *args, **kwargs)
    
    def critical(self, message: str, *args, **kwargs):
        """记录严重错误"""
        self.logger.critical(message, *args, **kwargs)
    
    def exception(self, message: str, *args, **kwargs):
        """记录异常（包含堆栈信息）"""
        self.logger.exception(message, *args, **kwargs)
    
    def log_download_start(self, url: str, save_path: str):
        """记录下载开始"""
        self.info(f"开始下载: {url} -> {save_path}")
    
    def log_download_progress(self, url: str, progress: float):
        """记录下载进度"""
        self.debug(f"下载进度: {url} - {progress:.1f}%")
    
    def log_download_complete(self, url: str, save_path: str, file_size: int):
        """记录下载完成"""
        self.info(f"下载完成: {url} -> {save_path} ({file_size} bytes)")
    
    def log_download_error(self, url: str, error: Exception):
        """记录下载错误"""
        self.error(f"下载失败: {url} - {str(error)}")
    
    def log_cookie_update(self, platform: str, cookie_count: int):
        """记录Cookie更新"""
        self.info(f"Cookie更新: {platform} - {cookie_count} 项")
    
    def log_config_change(self, key: str, old_value, new_value):
        """记录配置变更"""
        self.info(f"配置变更: {key} {old_value} -> {new_value}")


# 全局日志管理器实例
logger_manager = LoggerManager()


# 便捷函数
def get_logger(name: Optional[str] = None) -> LoggerManager:
    """获取日志管理器实例"""
    if name and name != logger_manager.name:
        return LoggerManager(name)
    return logger_manager


def log_debug(message: str, *args, **kwargs):
    """记录调试信息的便捷函数"""
    logger_manager.debug(message, *args, **kwargs)


def log_info(message: str, *args, **kwargs):
    """记录信息的便捷函数"""
    logger_manager.info(message, *args, **kwargs)


def log_warning(message: str, *args, **kwargs):
    """记录警告的便捷函数"""
    logger_manager.warning(message, *args, **kwargs)


def log_error(message: str, *args, **kwargs):
    """记录错误的便捷函数"""
    logger_manager.error(message, *args, **kwargs)


def log_exception(message: str, *args, **kwargs):
    """记录异常的便捷函数"""
    logger_manager.exception(message, *args, **kwargs)


def performance_monitor(func: Callable) -> Callable:
    """
    性能监控装饰器

    Args:
        func: 要监控的函数

    Returns:
        装饰后的函数
    """
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        func_name = f"{func.__module__}.{func.__name__}"

        try:
            result = func(*args, **kwargs)
            execution_time = time.time() - start_time

            # 记录性能信息
            if execution_time > 1.0:  # 超过1秒的操作记录为警告
                log_warning(f"性能警告: {func_name} 执行时间 {execution_time:.2f}s")
            else:
                log_debug(f"性能监控: {func_name} 执行时间 {execution_time:.2f}s")

            return result

        except Exception as e:
            execution_time = time.time() - start_time
            log_error(f"函数执行失败: {func_name} (执行时间 {execution_time:.2f}s) - {e}")
            raise

    return wrapper


def download_monitor(func: Callable) -> Callable:
    """
    下载监控装饰器

    Args:
        func: 要监控的下载函数

    Returns:
        装饰后的函数
    """
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        func_name = f"{func.__module__}.{func.__name__}"

        # 尝试从参数中提取URL信息
        url = "未知"
        if args:
            if isinstance(args[0], str) and args[0].startswith('http'):
                url = args[0][:50] + "..." if len(args[0]) > 50 else args[0]

        log_info(f"开始下载: {func_name} - {url}")

        try:
            result = func(*args, **kwargs)
            execution_time = time.time() - start_time

            if result:
                log_info(f"下载成功: {func_name} - {url} (耗时 {execution_time:.2f}s)")
            else:
                log_warning(f"下载失败: {func_name} - {url} (耗时 {execution_time:.2f}s)")

            return result

        except Exception as e:
            execution_time = time.time() - start_time
            log_error(f"下载异常: {func_name} - {url} (耗时 {execution_time:.2f}s) - {e}")
            raise

    return wrapper
